<?php
/**
 * This is interface for storage via local storage engine
 * @package     nuo
 * @subpackage  nuo.storage
 * @author      Nam Nguyen <nam.ngvan@gmail.com>
 * @version     1.0
 * @since       Apr 19, 2013
 */
class Nuo_Storage_Local extends Nuo_Storage_Abstract
{

	/**
	 * @param array $config
	 * @return void
	 */
	public function __construct($config)
	{
		extract($config, EXTR_SKIP);

		$this -> setId($id);
		$this -> setBaseUrl($baseUrl);
		$this -> setBasePath($basePath);
	}

	/**
	 * base url
	 * @var string
	 */
	function setBaseUrl($baseUrl)
	{
		$this -> _baseUrl = Nuo::getUrl('public') .'/';
	}

	/**
	 * @param string $basePath
	 */
	function setBasePath($basePath)
	{
		$this -> _basePath = 'public/';
		return $this;
	}

	/**
	 * @see Nuo::getApi('core/storage')->copyLocalFile
	 * @param string $path
	 * @param string $local
	 * @return bool
	 * @throws Exception
	 */
	function get($path, $local)
	{
		self::_makeLocalDir(dirname($path));
		$remote_file = $this -> getPath($path);
		return Nuo::getApi('core/storage')->copyLocalFile($remote_file, $local);
	}

	/**
	 * @see Nuo::getApi('core/storage')->copyLocalFile
	 * @param string $path
	 * @param string $local
	 * @return bool
	 * @throws Exception
	 *
	 */
	function put($path, $local)
	{
		if (!is_file($local))
		{
			throw new Exception(strtr('file "{file}" does not exists.', array('{file}' => $local)));
		}

		$file = $this -> getPath($path);

		$this -> makeDir(dirname($path), 0777);

		if (!@copy($local, $file))
		{
			throw new Exception(strtr('could not copy "{from}" to "{to}"', array(
				'{from}' => $file,
				'{to}' => $local
			)));
		}
		@chmod($file, 0644);

		return TRUE;
	}

	/**
	 * @param string $path
	 * @return string
	 * @throws Exception
	 */
	function getContents($path)
	{
		$file = $this -> getPath($path);

		if (file_exists($file))
		{
			return @file_get_contents($file);
		}
		throw new Exception(strtr('File "{file}" does not exists!', array('{file}' => $file)));
	}

	/**
	 * @see Nuo::getApi('core/storage')->writeLocalFile
	 * @param string $path
	 * @param string $data
	 * @return bool
	 * @throws Exception
	 *
	 */
	function putContents($path, $data)
	{
		$file = $this -> getPath($path);
		$this -> makeDir(dirname($file));

		return Nuo::getApi('core/storage')->writeLocalFile($file, $data);
	}

	/**
	 * @see unlink
	 * @param string $path
	 * @return bool
	 * @throws Exception
	 *
	 */
	function delete($path)
	{
		$file = $this -> getPath($path);

		if (!file_exists($file))
		{
			throw new Exception(strtr('File {file} does not exists!', array('{file}' => $file)));
		}

		if (!@unlink($file))
		{
			throw new Exception(strtr('File "{file}" could not be removed!', array('{file}' => $file)));
		}
		return TRUE;
	}

	/**
	 * @param string $path
	 * @return bool
	 */
	function isFile($path)
	{
		return @file_exists($this -> getPath($path));
	}

	/**
	 * @param string $path
	 * @return bool
	 */
	function isDir($path)
	{
		return is_dir($this -> getPath($path));
	}

	/**
	 * @param string $path
	 * @return bool
	 * @throws Exception
	 */
	function makeDir($path, $mode = 0755)
	{
		$dir = $this -> getPath($path);

		if (is_dir($dir))
		{
			return TRUE;
		}

		$parts = array_filter(explode('/', $dir));

		$pPath = array_shift($parts);

		while (count($parts) > 0)
		{
			$pPath .= '/' . array_shift($parts);

			// If it doesn't exist, create it
			if (!is_dir($pPath))
			{
				if (!@mkdir($pPath))
				{
					throw new Exception(strtr('Unable to make directory "{dir}"', array('{dir}' => $pPath)));
				}
				@chmod($pPath, $mode);
			}
		}

		if (!is_dir($dir))
		{
			throw new Exception(strtr('Unable to make directory "{dir}"', array('dir' => $dir)));
		}
		return TRUE;
	}

}
